/**
 * 
 */
package org.paybiz.core.payplatform.tenPay.service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URL;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.paybiz.component.xml.xmlparse.XmlHelper;
import org.paybiz.constant.PayConstant;
import org.paybiz.core.payplatform.tenPay.bean.TenTransferDetail;
import org.paybiz.core.payplatform.tenPay.bean.TenTransferInfo;
import org.paybiz.core.payplatform.tenPay.bean.TenTransferQueryInfo;
import org.paybiz.core.payplatform.tenPay.bean.TenTransferQueryResult;
import org.paybiz.core.payplatform.tenPay.bean.TenTransferResult;
import org.paybiz.core.payplatform.tenPay.constant.TenPayConstant;
import org.paybiz.core.payplatform.tenPay.constant.TenTransferConstant;
import org.paybiz.core.payplatform.tenPay.util.TenpayUtil;
import org.paybiz.util.DateUtil;
import org.paybiz.util.DynamicConfig;
import org.springframework.stereotype.Service;

/**
 * @author nassir wen
 * @date 2011-9-28
 * @version V2.5
 * @Company: MSD.
 * @Copyright Copyright (c) 2011
 */
@Service("tenTransferToBank")
public class TenTransferToBankImpl implements TenTransferToBank {
    private final static Log logger = LogFactory.getLog(TenTransferToBankImpl.class);

    private static String op_user = "";// 操作员ID

    private static String op_passwd = "";// 操作员密码

    private static String sp_id = "";// 商户机构ID

    private static String tenKey = "";//key

    private static String transferUrl = ""; //转账链接
    static {
        op_user = DynamicConfig.getInstance().getValue(TenPayConstant.TEN_MERID);
        op_passwd = DynamicConfig.getInstance().getValue(TenPayConstant.TEN_PASSWD);
        sp_id = DynamicConfig.getInstance().getValue(TenPayConstant.TEN_SP_ID);
        tenKey = DynamicConfig.getInstance().getValue(TenPayConstant.TEN_KEYVALUE);
        transferUrl = DynamicConfig.getInstance().getValue(TenPayConstant.TEN_TRANSFERURL);
    }

    @Override
    public TenTransferResult transferToBank(TenTransferInfo transferInfo) {
        // TODO Auto-generated method stub
        if (logger.isInfoEnabled()) {
            logger.info("begin..." + transferInfo.toString());
        }
        //生成xml数据报文
        String xmlStr = tenPayTransferInputXml(transferInfo);
        String base64Str = "";
        try {
            base64Str = TenpayUtil.encodeString(xmlStr, "GB2312");
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        String sign = TenpayUtil.createTransferSign(base64Str, tenKey, "GB2312");
        String url = new StringBuilder(transferUrl).append("?content=").append(base64Str).append("&abstract=")
                .append(sign).toString();
        TenTransferResult result = new TenTransferResult();
        String returnStr = "";
        try {
            if (logger.isInfoEnabled()) {
                logger.info("transferUrl : " + url);
            }
            Document doc = XmlHelper.createDoc(new URL(url).openStream());
            //解析返回信息
            String retcode = XmlHelper.getNode(doc, "//root/retcode").getText();
            result.setRetcode(retcode);
            if (!StringUtils.equals(retcode, TenTransferConstant.SUC_0)
                    && !StringUtils.equals(retcode, TenTransferConstant.SUC_00)) {
                String retmsg = XmlHelper.getNode(doc, "//root/retmsg").getText();
                result.setRetmsg(retmsg);
            }
            result.setResult(PayConstant.RESULT_SUCCESS);
        } catch (SocketTimeoutException ste) {
            returnStr = "服务器连接超时";
            logger.error(returnStr, ste);
            result.setResult(PayConstant.RESULT_FAIL);
            result.setErrMsg(returnStr);
        } catch (Exception e) {
            logger.error(returnStr, e);
            returnStr = "转账请求异常";
            result.setResult(PayConstant.RESULT_FAIL);
            result.setErrMsg(returnStr);
            logger.error(returnStr, e);
        }
        return result;
    }

    @Override
    public TenTransferQueryResult transferQuery(TenTransferQueryInfo transferQueryInfo) {
        if (logger.isInfoEnabled()) {
            logger.info("begin..." + transferQueryInfo.toString());
        }
        //生成xml数据报文
        String xmlStr = tenPayTransferQueryXml(transferQueryInfo);
        String base64Str = "";
        try {
            base64Str = TenpayUtil.encodeString(xmlStr, "GB2312");
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        String sign = TenpayUtil.createTransferSign(base64Str, tenKey, "GB2312");
        String url = new StringBuilder(transferUrl).append("?content=").append(base64Str).append("&abstract=")
                .append(sign).toString();
        TenTransferQueryResult result = new TenTransferQueryResult();
        String returnStr = "";
        try {
            if (logger.isInfoEnabled()) {
                logger.info("transferQueryUrl : " + url);
            }
            Document doc = XmlHelper.createDoc(new URL(url).openStream());
            //解析返回信息
            String retcode = XmlHelper.getNode(doc, "//root/retcode").getText();
            result.setRetcode(retcode);
            result.setResult(PayConstant.RESULT_SUCCESS);
            if (StringUtils.equals(retcode, TenTransferConstant.SUC_0)
                    || StringUtils.equals(retcode, TenTransferConstant.SUC_00)) {
                String origin_total = XmlHelper.getNode(doc, "//root/origin_set/origin_total").getText();
                if (logger.isInfoEnabled()) {
                    logger.info("origin_total: " + origin_total);
                }
                if (!StringUtils.equals(origin_total, "0")) {
                    result.setTransfer_status(TenTransferConstant.TRANSFER_ORIGIN);
                    return result;
                }
                String suc_total = XmlHelper.getNode(doc, "//root/suc_total/suc_total").getText();
                if (logger.isInfoEnabled()) {
                    logger.info("suc_total: " + suc_total);
                }
                if (!StringUtils.equals(suc_total, "0")) {
                    result.setTransfer_status(TenTransferConstant.TRANSFER_ORIGIN);
                    return result;
                }
                String tobank_total = XmlHelper.getNode(doc, "//root/tobank_set/tobank_total").getText();
                if (logger.isInfoEnabled()) {
                    logger.info("tobank_total: " + tobank_total);
                }
                if (!StringUtils.equals(tobank_total, "0")) {
                    result.setTransfer_status(TenTransferConstant.TRANSFER_ORIGIN);
                    return result;
                }
                String fail_total = XmlHelper.getNode(doc, "//root/fail_set/fail_total").getText();
                if (logger.isInfoEnabled()) {
                    logger.info("fail_total: " + fail_total);
                }
                if (!StringUtils.equals(fail_total, "0")) {
                    result.setTransfer_status(TenTransferConstant.TRANSFER_ORIGIN);
                    return result;
                }
                String handling_total = XmlHelper.getNode(doc, "//root/handling_set/handling_total").getText();
                if (logger.isInfoEnabled()) {
                    logger.info("handling_total: " + handling_total);
                }
                if (!StringUtils.equals(handling_total, "0")) {
                    result.setTransfer_status(TenTransferConstant.TRANSFER_ORIGIN);
                    return result;
                }
            } else {
                String retmsg = XmlHelper.getNode(doc, "//root/retmsg").getText();
                result.setRetmsg(retmsg);
            }
        } catch (SocketTimeoutException ste) {
            returnStr = "服务器连接超时";
            logger.error(returnStr, ste);
            result.setResult(PayConstant.RESULT_FAIL);
            result.setErrMsg(returnStr);
        } catch (Exception e) {
            logger.error(returnStr, e);
            returnStr = "转账请求异常";
            result.setResult(PayConstant.RESULT_FAIL);
            result.setErrMsg(returnStr);
            logger.error(returnStr, e);
        }
        return result;
    }

    //生成转账数据报文
    private String tenPayTransferInputXml(TenTransferInfo transferInfo) {
        Document doc = XmlHelper.createDoc();
        //设置编码
        doc.setXMLEncoding("GB2312");
        Element root = doc.addElement("root");
        Element op_code = root.addElement("op_code");
        Element op_name = root.addElement("op_name");
        Element op_user = root.addElement("op_user");
        Element op_passwd = root.addElement("op_passwd");
        Element op_time = root.addElement("op_time");
        Element sp_id = root.addElement("sp_id");
        Element package_id = root.addElement("package_id");
        Element total_num = root.addElement("total_num");
        Element total_amt = root.addElement("total_amt");
        Element client_ip = root.addElement("client_ip");
        op_code.setText(transferInfo.getOp_code());
        op_name.setText("batch_draw");
        op_user.setText(TenTransferToBankImpl.op_user);
        op_passwd.setText(TenTransferToBankImpl.op_passwd);
        op_time.setText(transferInfo.getOp_time());
        sp_id.setText(TenTransferToBankImpl.sp_id);
        package_id.setText(transferInfo.getPackage_id());
        total_num.setText(transferInfo.getTotal_num());
        total_amt.setText(transferInfo.getTotal_amt());
        client_ip.setText(transferInfo.getClient_ip());
        //付款记录
        for (int i = 0; i < transferInfo.getTenTransfeDetails().size(); i++) {
            TenTransferDetail detail = transferInfo.getTenTransfeDetails().get(i);
            Element record_set = root.addElement("record_set");
            Element record = record_set.addElement("record");
            Element serial = record.addElement("serial");
            Element rec_bankacc = record.addElement("rec_bankacc");
            Element bank_type = record.addElement("bank_type");
            Element rec_name = record.addElement("rec_name");
            Element pay_amt = record.addElement("pay_amt");
            Element acc_type = record.addElement("acc_type");
            Element area = record.addElement("area");
            Element city = record.addElement("city");
            Element subbank_name = record.addElement("subbank_name");
            Element desc = record.addElement("desc");
            serial.setText(detail.getSerial());
            rec_bankacc.setText(detail.getRec_bankacc());
            bank_type.setText(detail.getBank_type());
            rec_name.setText(detail.getRec_name());
            pay_amt.setText(detail.getPay_amt());
            acc_type.setText(detail.getAcc_type());
            area.setText(detail.getArea());
            city.setText(detail.getCity());
            subbank_name.setText(detail.getSubbank_name());
            desc.setText(detail.getDesc());
        }
        String xmlStr = XmlHelper.outXmlStr(doc);
        if (logger.isInfoEnabled()) {
            logger.info("transfer xml: " + xmlStr);
        }
        try {
            logger.info("输出报文文件: " + "/home/logs/pay-biz/tenTransfer" + DateUtil.getDateToString() + ".xml");
            XmlHelper.saveXml("/home/logs/pay-biz/tenTransfer" + DateUtil.getDateToString() + ".xml", doc);
        } catch (IOException e) {
            logger.error(e);
        }
        return xmlStr;
    }

    //生成转账数据报文 
    private String tenPayTransferQueryXml(TenTransferQueryInfo transferQueryInfo) {
        Document doc = XmlHelper.createDoc();
        //设置编码
        doc.setXMLEncoding("GB2312");
        Element root = doc.addElement("root");
        Element op_code = root.addElement("op_code");
        Element op_name = root.addElement("op_name");
        Element op_user = root.addElement("op_user");
        Element op_passwd = root.addElement("op_passwd");
        Element op_time = root.addElement("op_time");
        Element sp_id = root.addElement("sp_id");
        Element package_id = root.addElement("package_id");
        Element client_ip = root.addElement("client_ip");
        op_code.setText(transferQueryInfo.getOp_code());
        op_name.setText("batch_draw_query");
        op_user.setText(TenTransferToBankImpl.op_user);
        op_passwd.setText(TenTransferToBankImpl.op_passwd);
        sp_id.setText(TenTransferToBankImpl.sp_id);
        op_time.setText(transferQueryInfo.getOp_time());
        package_id.setText(transferQueryInfo.getPackage_id());
        client_ip.setText(transferQueryInfo.getClient_ip());
        String xmlStr = XmlHelper.outXmlStr(doc);
        if (logger.isInfoEnabled()) {
            logger.info("transfer query xml: " + xmlStr);
        }
        try {
            logger.info("输出报文文件: " + "/home/logs/pay-biz/tenTransfer" + DateUtil.getDateToString() + ".xml");
            XmlHelper.saveXml("/home/logs/pay-biz/tenTransfer" + DateUtil.getDateToString() + ".xml", doc);
        } catch (IOException e) {
            logger.error(e);
        }
        return xmlStr;
    }
}
